const request = require('base')

/**
 * 云请求处理中心。
 * 增删改查等以及外链的访问方法
 */
module.exports = {
	_before: function () {
		request.handleBefore(this, undefined, undefined, true)
	},
	
	_after(error, result) {
		return request.handleAfter(this, error, result, true)
	},
	
	/**
	 * url请求。提供给前端调用
	 * @param {String} url：请求地址
	 * @param {Object} params：请求参数
	 */
	url(params) {
		const {httpInfo} = request.common
		if (httpInfo) {
			params = httpInfo.query.params
		}
		if (params && params.url) {
			const {
				url,
				data = {},
				method = 'GET',
				headers = {
					contentType: 'application/json;charset=utf-8'
				},
				content, // POST模式下用form拼接的参数
				timeout = 5000,
				dataType = 'json', // 指定返回值为json格式，自动进行parse
				contentType = 'json', // 指定以application/json发送data内的数据
			} = params || {}
			return request.url(url, {data, method, headers, content, timeout, dataType, contentType})
		}
		return {
			errCode: 'PARAM_IS_NULL',
			errMsg: '没有URL地址'
		}
	},
	
	/**
	 * 增加一个或多个数据
	 * @param {Object} params
	 *  space：云服务空间名称。只有特定的已知场景，需要对其他类型的云服务空间操作，才需要传
	 * 	name：数据库名称
	 * 	data：要增加的数据。对象或者对象数组
	 * 	isReturn：是否返回新增后的数据
	 * 	addType：不满足必要性和唯一性条件的判断和处理
	 * 		requiredType = -1，忽略必要性判断；0：不新增；1：仍然新增（就会导致必要的数据不完整）
	 * 		onlyType = -1 -1，忽略唯一性判断；0：不新增；1：修改原数据（只修改本次已有的）；2：覆盖原数据（会保留_id）；3：覆盖原数据（不保留_id）
	 * 		onlyKeys, 自定义的唯一性字段集合，同数据库配置设置，二维数组
	 * 		required, 自定义的必要性字段集合，同数据库配置设置，一维数组
	 */
	add(params) {
		const {httpInfo} = request.common
		if (httpInfo) {
			params = httpInfo.query.params
		}
		const {name, data, isReturn, addType} = params
		if (name && data) {
			return request.add(params)
		}
		return {
			errCode: 'PARAMS_IS_UNLEGAL',
			errMsg: '新增参数不合法'
		} 
	},
	
	/**
	 * 删除一个或多个数据
	 * @param {Object} params
	 *  space：云服务空间名称。只有特定的已知场景，需要对其他类型的云服务空间操作，才需要传
	 * 	name：数据库名称
	 * 	doc：要删除的字符串，可以是数组。优先级最大
	 * 	where：其他要删除的条件。可以是‘all’，表示删除全部，其它字符串表示jql语法。如果是对象，表示删除的查询条件
	 * 	isDelete：是否真的删除数据
	 * 
	 * 删除时务必注意select类型查询时，必须保证每一个都有值，否则会删除所有数据！
	 */
	remove(params) {
		const {httpInfo} = request.common
		if (httpInfo) {
			params = httpInfo.query.params
		}
		const {name, doc, where} = params
		if (name && (doc || where)) {
			return request.remove(params)
		}
		return {
			errCode: 'PARAMS_IS_UNLEGAL',
			errMsg: '删除参数不合法'
		}
	},
	
	/**
	 * 删除满足条件的数据后，全部清除，然后新增
	 * 该方法是纯覆盖新增，_id会完全改变
	 * @param {Object} params
	 *  space：云服务空间名称。只有特定的已知场景，需要对其他类型的云服务空间操作，才需要传
	 * 	name：数据库名称
	 * 	doc：要删除的字符串，可以是数组。优先级最大
	 * 	where：其他要删除的条件。字符串表示jql语法。如果是对象，表示删除的查询条件
	 * 	data：需要新增的数据，一般是数组。内部有判断添加where中的非对象数据，若要保证准确性，请在调用前处理
	 *  isDelete：是否真的删除数据
	 *  isReturn：是否返回修改后的完整数据
	 */
	removeAdd(params) {
		const {httpInfo} = request.common
		if (httpInfo) {
			params = httpInfo.query.params
		}
		const {name, data} = params
		if (name && data) {
			return request.removeAdd(params)
		}
		return {
			errCode: 'TABLE_IS_ULL',
			errMsg: '数据库或新增的内容不存在'
		}
	},
	
	/**
	 * 修改一条或多条数据
	 * @param {Object} params
	 *  space：云服务空间名称。只有特定的已知场景，需要对其他类型的云服务空间操作，才需要传
	 * 	name：数据库名称
	 * 	doc：要修改的数据的字符串，可以是数组。优先级最大
	 * 	where：其他要修改的条件。字符串表示jql语法。如果是对象，表示修改的查询条件
	 * 	data：需要修改的内容，只能是对象
	 *  isReturn：是否返回修改后的完整数据
	 */
	alert(params) {
		const {httpInfo} = request.common
		if (httpInfo) {
			params = httpInfo.query.params
		}
		const {name, doc, where, data} = params
		if (name && (doc || where) && data) {
			return request.alert(params)
		}
		return {
			errCode: 'PARAMS_IS_UNLEGAL',
			errMsg: '修改参数不合法'
		} 
	},
	
	/**
	 * 修改新增数据。有则修改，无则新增
	 * @param {Object} params
	 *  space：云服务空间名称。只有特定的已知场景，需要对其他类型的云服务空间操作，才需要传
	 * 	name：数据库名称
	 * 	doc：要修改的数据的字符串，可以是数组。优先级最大
	 * 	where：其他要修改的条件。字符串表示jql语法。如果是对象，表示修改的查询条件
	 * 	data：需要新增或修改的内容，只能是对象
	 *  isReturn：是否返回修改后的完整数据
	 */
	addAlert(params) {
		const {httpInfo} = request.common
		if (httpInfo) {
			params = httpInfo.query.params
		}
		const {name, doc, where, data} = params
		if (name && data) {
			return request.addAlert(params)
		}
		return {
			errCode: 'PARAMS_IS_UNLEGAL',
			errMsg: '编辑参数不合法'
		}
	},
	
	/**
	 * 查询数据
	 * @param {Object} params
	 *  space：云服务空间名称。只有特定的已知场景，需要对其他类型的云服务空间操作，才需要传
	 * 	name：数据库名称
	 * 	doc：要查询的数据的字符串，可以是数组。优先级最大
	 * 	where：其他要查询的条件。字符串表示jql语法。如果是对象，表示修改的查询条件
	 * 	pagination：页码控制器。pageSize和pageIndex必须生效
	 *  ……其它参数见handleWhere
	 */
	get(params) {
		const {httpInfo} = request.common
		if (httpInfo) {
			params = httpInfo.query.params
		}
		const {name, doc, where} = params
		if (name && (doc || where)) {
			return request.get(params)
		}
		return {
			errCode: 'PARAMS_IS_UNLEGAL',
			errMsg: '查询参数不合法'
		}
	},
	
	/**
	 * 只查询数量
	 * @param {Object} params 查询条件 同get
	 */
	getCount(params) {
		const {httpInfo} = request.common
		if (httpInfo) {
			params = httpInfo.query.params
		}
		const {name, doc, where} = params
		if (name && (doc || where)) {
			params.OnlyCount = true
			return request.get(params)
		}
		return {
			errCode: 'PARAMS_IS_UNLEGAL',
			errMsg: '查询参数不合法'
		}
	},
	
	/**
	 * 生成一个编码
		type, 要生成的编码类型。0-短编码，1-默认编码，2-简洁编码，3-层级编码，4-其它未定义编码
		uid, 用户id或者原始值
		mode, 该编码模式。1-纯数字，2-纯小写，3-纯大写，4-数字+小写，5-数字+大写，6-小写+大写，7-数字+小写+大写
		length, 额外长度
		
		BM, 编码前缀
		XM, 项目前缀
		
		space, 云服务名称
		name, 数据库名称
		remark, 编码的备注信息
		
		register = true 是否注册到数据库以备案
	 */
	getCode(params) {
		const {httpInfo} = request.common
		if (httpInfo) {
			params = httpInfo.query.params
		}
		return request.getCode(params)
	},
	
	/**
	 * 复制一个数据
	 * @param {Object} params 查询条件 同get
	 * 	space：云服务空间名称。一般就是本服务空间
	 * 	name：数据库名称
	 * 	_id或者doc：要复制的数据id
	 * 	code：原始数据的code值，表示复制该数据需要生成新的code(根据编码规则获取编码前缀和项目前缀)，否则不需要
	 * 
	 * 1，名称和唯一项，前面都添加一个副本。这一步在addData中控制
	 * 2，原code存在，重新获取code
	 * 3，默认去除的信息：
	 * 	"_id", "remark", "creator", "timestamp", "alert_user", "alert_time", "remove"
	 * 4，默认的信息
	 * creat_type：4
	 * HISTORY：[{_id: '原id'}]
	 */
	copy(params) {
		const {httpInfo} = request.common
		if (httpInfo) {
			params = httpInfo.query.params
		}
		const {name, doc, _id} = params
		if (name && (doc || _id)) {
			return request.copy(params)
		}
		return {
			errCode: 'PARAMS_IS_UNLEGAL',
			errMsg: '查询参数不合法'
		}
	},
	
	/**
	 * 获取一个数据库的表单信息
	 * 暂不支持其它云服务空间的数据库查询
	 */
	table(params) {
		const {httpInfo} = request.common
		if (httpInfo) {
			params = httpInfo.query.params
		}
		const {name, space} = params
		if (name) {
			return request.dbGet(name)
		}
		return {
			errCode: 'PARAMS_IS_UNLEGAL',
			errMsg: '查询参数不合法'
		}
	}
}